#ifndef PLCSYMBOLTABLE_H_
#define PLCSYMBOLTABLE_H_

#include <map>
#include <string>

#include <plc2llvm/SymbolRecord.h>
#include <plc2llvm/PLCSymbols/ImportScope.h>
// #include <plc2llvm/PLCScope.h>


class PLCSymbol;

class SymbolRecord;

class PLCSymbolTable {
private:
    //与符号表相关联的符号
    ImportScope* importSymbol;
    //与符号表相关联的作用域
    PLCScope* scope;

    //当前作用域内，以名称索引的表
    std::map<std::string, PLCSymbol*> nameMap;
    //当前作用域内，以symbol id索引的表, 可能弃用
    std::map<int, PLCSymbol*> idMap;

    //关联所有使用的命名空间、父作用域的表，用于查找的符号记录
    std::map<std::string, SymbolRecord*> recordMap;

public:
    PLCSymbolTable(ImportScope* importSymbol, PLCScope* scope);

    const std::map<std::string, SymbolRecord *> &getRecordMap() const;

    void setImportSymbol(ImportScope* importSymbol);
    ImportScope* getImportSymbol();

    void setScope(PLCScope* scope);
    PLCScope* getScope();

    //向所有的map添加符号（仅限添加本作用域的符号）
    void addFromLocal(PLCSymbol* symbol);

    //从相关联的作用域内获得符号
    void addAlternativeSymbolsFromTable(PLCSymbolTable* another);

    //单独添加备选符号
    void addAlternativeSymbol(PLCSymbol* alternativeSymbol);

    //根据名称在本作用域的名称表内寻找
    PLCSymbol* getSymbolByNameFromLocalNameMap(std::string name);

    //根据symbol id在本作用域内寻找
    PLCSymbol* getSymbolByIdFromLocal(int id);

    //根据名称在本作用域以及与本作用域相关联的作用域(recordMap)内寻找
    PLCSymbol* getSymbolByNameFromLocalRecord(std::string name);

};

#endif
